Skip to content

fix(windows): Crash on app startup when Media Feature Pack is not installed on Windows N#2019

Merged
Gustl22 merged 26 commits into
mainfrom
gustl22/windows-n
Jul 23, 2026
Merged

fix(windows): Crash on app startup when Media Feature Pack is not installed on Windows N#2019
Gustl22 merged 26 commits into
mainfrom
gustl22/windows-n

Conversation

@Gustl22

@Gustl22 Gustl22 commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Description

Fixes crash on missing Media Feature Pack on N and KN versions of Windows (European and Korean)
Now plugin uses delayed load mechanism for important dlls and provides errors accordingly.

Checklist

  • The title of my PR starts with a Conventional Commit prefix (fix:, feat:, refactor:,
    docs:, chore:, test:, ci: etc).
  • I have read the Contributor Guide and followed the process outlined for submitting PRs.
  • I have updated/added tests for ALL new/updated/fixed functionality.
  • I have updated/added relevant documentation and added dartdoc comments with ///, where necessary.
  • I have updated/added relevant examples in example.

Breaking Change

  • Yes, this is a breaking change.
  • No, this is not a breaking change.

Related Issues

Fixes #1956

@Gustl22

Gustl22 commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator Author

@krll-kov @13thdeus can you test this branch on your Windows N machine?

@krll-kov

Copy link
Copy Markdown
Contributor

@krll-kov @13thdeus can you test this branch on your Windows N machine?

I'm not sure what I'm supposed to test. This fix does not fix anything, app crash happens in different place in different file, audio_player.cpp

Problem occurs not when you execute the code, it happens even before the app executes flutters main function, upon register somewhere in flutter engine, before app window is created

That's why you need to wrap full

AudioPlayer::AudioPlayer(
std::string playerId,
flutter::MethodChannelflutter::EncodableValue* methodChannel,
EventStreamHandler<>* eventHandler)
: _playerId(playerId),
_methodChannel(methodChannel),
_eventHandler(eventHandler) {

Into try catch and add library presence check there , that's the base minimum

@krll-kov

Copy link
Copy Markdown
Contributor

@krll-kov @13thdeus can you test this branch on your Windows N machine?

As for the crash you mentioned in other pr, I'm not sure why it happens for you, I spent a few days testing previous version and it worked okay, try building in release mode and launching app through visual studio debugger, so that we can see where it happens

@Gustl22

Gustl22 commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator Author

Apparently the CI is not agreeing with me. I did test on usual Windows and Windows 11 N though...

This fix does not fix anything, app crash happens in different place in different file, audio_player.cpp

@krll-kov The code part "AudioPlayer" isn't even initialized in my code implementation, so therefore cannot crash. It doesn't make sense to initialize a player, which cannot be used.

@Gustl22
Gustl22 marked this pull request as draft July 22, 2026 20:29
@krll-kov

Copy link
Copy Markdown
Contributor

Apparently the CI is not agreeing with me. I did test on usual Windows and Windows 11 N though...

@krll-kov The code part "AudioPlayer" isn't even initialized in my code implementation, so therefore cannot crash. It doesn't make sense to initialize a player, which cannot be used.

AudioPlayer is never dynamically instantiated because of the if (isMediaFoundationSupported) check. But you are thinking about Runtime, while the crash is happening at Load-time (before the app's main() even starts).

Because audio_player.cpp uses Media Foundation functions (like MFStartup), the compiler adds mfplat.dll and mfreadwrite.dll to the plugin's Import Address Table (IAT).
When the Flutter app launches, the Windows OS loader walks through the IAT. It sees that mfplat.dll is required, tries to find it, fails (because it's Windows N or Windows Server in CI), and immediately kills the process with exception.

The OS kills the app before AudioplayersWindowsPlugin gets to run its CheckMediaFoundationSupport() logic. That's why C++ if checks don't prevent the crash.

@krll-kov

Copy link
Copy Markdown
Contributor

Apparently the CI is not agreeing with me. I did test on usual Windows and Windows 11 N though...

This fix does not fix anything, app crash happens in different place in different file, audio_player.cpp

@krll-kov The code part "AudioPlayer" isn't even initialized in my code implementation, so therefore cannot crash. It doesn't make sense to initialize a player, which cannot be used.

By the way since fix was created, flutter introduced merged thread that changed a lot of things in plugin behavior, so that also could change what we see now with crash you mentioned

@Gustl22

Gustl22 commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator Author

But you are thinking about Runtime, while the crash is happening at Load-time (before the app's main() even starts).
...
When the Flutter app launches, the Windows OS loader walks through the IAT. It sees that mfplat.dll is required, tries to find it, fails (because it's Windows N or Windows Server in CI), and immediately kills the process with exception.

But that's exactly what this change is for, so it happens at runtime, not startup / load time, what you did exactly the same in your implementation target_link_options(${PLUGIN_NAME} PRIVATE "/DELAYLOAD:Mfplat.dll"):
https://github.com/bluefireteam/audioplayers/pull/2019/changes#diff-5c9520582156e7e19f4d55dcf104fa9178cc0e75ef43a316d68b50f90c7e8772R60

Otherwise your check always would have been unnecessary if (!hMfplat || !hMfreadwrite) {: https://github.com/bluefireteam/audioplayers/pull/1957/changes#diff-aa78a794181ed180e10613f782a132181680c4b986683ae2cc3b1336265ba3c5R34

Into try catch and add library presence check there , that's the base minimum

In your implementation you call try catch after the dynamic library loading, so it wouldn't have an effect. Apparently the check works upfront without any try catch:
https://github.com/bluefireteam/audioplayers/pull/1957/changes#diff-aa78a794181ed180e10613f782a132181680c4b986683ae2cc3b1336265ba3c5R44

And I tested my implementation: it did not initialize the player on Windows N system with the desired error messages, and it did initialize on a normal System and played the audio.

By the way since fix was created, flutter introduced merged thread that changed a lot of things in plugin behavior, so that also could change what we see now with crash you mentioned

Thread merging apparently nothing has to do with plugin handling, they were always supposed to be on the same thread:
flutter/flutter#150525 (comment)
and flutter/flutter#150525 (comment)

But the thread switch helper function was added recently to Flutter:
flutter/flutter#79213

@krll-kov

Copy link
Copy Markdown
Contributor

But you are thinking about Runtime, while the crash is happening at Load-time (before the app's main() even starts).
...
When the Flutter app launches, the Windows OS loader walks through the IAT. It sees that mfplat.dll is required, tries to find it, fails (because it's Windows N or Windows Server in CI), and immediately kills the process with exception.

But that's exactly what this change is for, so it happens at runtime, not startup / load time, what you did exactly the same in your implementation target_link_options(${PLUGIN_NAME} PRIVATE "/DELAYLOAD:Mfplat.dll"): https://github.com/bluefireteam/audioplayers/pull/2019/changes#diff-5c9520582156e7e19f4d55dcf104fa9178cc0e75ef43a316d68b50f90c7e8772R60

Otherwise your check always would have been unnecessary if (!hMfplat || !hMfreadwrite) {: https://github.com/bluefireteam/audioplayers/pull/1957/changes#diff-aa78a794181ed180e10613f782a132181680c4b986683ae2cc3b1336265ba3c5R34

Into try catch and add library presence check there , that's the base minimum

In your implementation you call try catch after the dynamic library loading, so it wouldn't have an effect. Apparently the check works upfront without any try catch: https://github.com/bluefireteam/audioplayers/pull/1957/changes#diff-aa78a794181ed180e10613f782a132181680c4b986683ae2cc3b1336265ba3c5R44

And I tested my implementation: it did not initialize the player on Windows N system with the desired error messages, and it did initialize on a normal System and played the audio.

#1956

I remember having this crash on my system even with delayload that happened before initialization of my app in flutters main function, so somehow that code was executed during internal initialization inside engine

Unhandled exception at 0x00007FFC310F804A (KernelBase.dll) in test.exe: 0xC06D007E: Module not found (parameters: 0x00000094F791F380).

I have no idea how, maybe some static initialization or complier optimizations but I'm 100 % sure I didn't even create a player and crash was already present

@Gustl22
Gustl22 marked this pull request as ready for review July 22, 2026 21:21
@Gustl22

Gustl22 commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator Author

I have no idea how, maybe some static initialization or complier optimizations but I'm 100 % sure I didn't even create a player and crash was already present

If you have reproducible steps, which crash despite the newly provided implementation, I am more than happy to let me convince. But, I see no reason to add a try catch, which isn't guaranteed to work.

@krll-kov

Copy link
Copy Markdown
Contributor

I have no idea how, maybe some static initialization or complier optimizations but I'm 100 % sure I didn't even create a player and crash was already present

If you have reproducible steps, which crash despite the newly provided implementation, I am more than happy to let me convince. But, I see no reason to add a try catch, which isn't guaranteed to work.

It's impossible to provide any steps since app just crashed upon launch before I even used any flutter code (after adding delayload that fixed initial dll absense error). Maybe something in package has changed within this year, or your windows n version is newer and behavior has changed or there's one more issue related to WinRT apartment initialization/some static initialization/something similar, I have no idea, but I'm sure that just checking for dll absense was not enough for some reason and somehow that code did trigger on launch.

One more thing I notice is that right now you use newer version of WIL
set(WIL_VERSION "1.0.260126.7"), it changes a lot of internal staff and last time I tried it, release version of plugin dll was marked as false positive on virus total. Not sure if that's already fixed, but I switched back to set(WIL_VERSION "1.0.210803.1"). You can try uploading current dll from release build to check if that's still the case

@Gustl22

Gustl22 commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

It's impossible to provide any steps since app just crashed

Maybe something in package has changed within this year

That's why I asked to test the new implementation (of this PR). We are discussing something, which was a year ago on assumptions, not on actual testing and reproducible steps.

dll was marked as false positive on virus total.

But that's a different issue. That error could stem from anything. I don't know what code you use on your side. We have to agree on a common test base, which in our case is the example. You need to understand, that we cannot simply trust any statement and go with it. That's the job of a review to test and evaluate consistently.

The issue was that the app crashes on Windows N system, which I could reproduce and fix in this common environment, based also on your solution.

I would have even liked to test it in CI on Windows N, but there are no runners or one must start a VM, which introduces far more overhead, than it actually solves.

If any further errors occur, we should find the source of it, so we know why it happens and can reliably fix it.

@krll-kov

Copy link
Copy Markdown
Contributor

error could stem from anything. I don't know what code you use on your side. We have to agree on a common test base, which in our case is the example. You need to understand, that we cannot simply trust any statement and go with it. That's the job of a review to test and evaluate consistently.

I tested this example and it works, you were right, too many things have changed in a year, right now there's no crash at that place, false positives are also gone

@Gustl22

Gustl22 commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

@krll-kov thank you for the time you invested to provide the initial fix and the testing.
If any more problems occur, feel free to open another issue and/or potential fix.

@Gustl22
Gustl22 merged commit cd475c7 into main Jul 23, 2026
84 of 85 checks passed
@Gustl22
Gustl22 deleted the gustl22/windows-n branch July 23, 2026 11:22
Sebastien-VZN pushed a commit to Sebastien-VZN/audioplayers that referenced this pull request Jul 23, 2026
Commits marqués comme analyses et non portes:
- 310304d ci: Upgrade CI Flutter version to v3.44.6 (bluefireteam#2014) — cosmétique CI
- 244a4a0 ci: Support verbose debugging in tests (bluefireteam#2015) — cosmétique CI
- 0b89829 test: Set timeouts for integration tests (bluefireteam#2016) — cosmétique tests
- 6efd636 refactor: Handle common ReleaseMode.release logic in Dart (bluefireteam#2017) — redondant, deja gere nativement
- fa6ec8e feat!: Add PlayingStateUpdate event (bluefireteam#1995) — over-engineering, 500 lignes pour rien
- cd475c7 fix(windows): Crash Windows N Media Feature Pack (bluefireteam#2019) — try-catch global du fork couvre deja le cas
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows 11 (N/KN) Silent crash of app on start because of absence of MFPlat.DLL

3 participants